package com.exam.security;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

@Configuration
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserLoadSecurityServiceImpl userLoadSecurityService;

//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userLoadSecurityService);
//    }

    /**
     * 配置HttpSecurity对象，用于设置Spring Security的安全策略
     *
     * @param http HttpSecurity对象
     * @throws Exception 异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 配置请求授权
        http.authorizeRequests()
                // 公共路径需要 "student", "teacher", "admin" 中的任意权限
                .mvcMatchers("/public/**").hasAnyAuthority("student", "teacher", "admin")
                // 学生相关路径需要 "student", "admin", "teacher" 中的任意权限
                .mvcMatchers("/student/**").hasAnyAuthority("student", "admin", "teacher")
                // 教师相关路径需要 "teacher", "admin" 中的任意权限
                .mvcMatchers("/teacher/**").hasAnyAuthority("teacher", "admin")
                // 管理员相关路径需要 "admin" 权限
                .mvcMatchers("/admin/**").hasAnyAuthority("admin")
                // 下面的路径不需要任何权限，可以直接访问
                // 配合下面的web.ignore 将下面所有的路径的校验都过滤掉了
                .mvcMatchers("/util/**", "/common/**", "/actuator/**", "/api/**").permitAll()

                // 其他所有请求都需要认证
                .anyRequest().authenticated()

                .and()

                // 添加Token认证过滤器，放在BasicAuthenticationFilter之前
                // token认证
                .addFilterBefore(new TokenAuthFilter(authenticationManager()), BasicAuthenticationFilter.class)

                // 配置认证异常处理器
                // 认证异常处理器
                .exceptionHandling()
                .accessDeniedHandler(new MyAccessDeniedHandler())
                .authenticationEntryPoint(new MyAuthenticationEntryPointHandler())

                // 关闭CSRF防护，默认开启针对 POST, PUT, PATCH 的 CSRF token 校验
                .and().csrf().disable();

        // 关闭表单登录
        http.formLogin().disable();

        // 前后端分离，关闭登出配置
        http.logout().disable();

        // 设置所有Rest服务为无状态，以提升操作性能
        // 所有的Rest服务一定要设置为无状态，以提升操作性能
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
                .antMatchers("/util/**", "/common/**")
                .antMatchers("/actuator/**")
                .antMatchers("/api/**")
                .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/v2/**");
    }
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
//    }
}
